package com.example.shop.common.shiro;

import com.example.shop.common.utils.Constants;
import com.example.shop.common.utils.RedisService;
import com.example.shop.domain.sys.SysUser;
import com.example.shop.sys.user.service.SysUserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Resource;
import java.util.*;

import static com.example.shop.common.utils.Constants.CURRENT_USER;

public class UserRealm extends AuthorizingRealm {


    @Resource
    private SysUserService sysUserService;
    @Autowired
    private RedisService redisService;

    /**
     * 授权(验证权限时调用)
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SysUser user = (SysUser) principals.getPrimaryPrincipal();

        Set<String> set = null;

        set = (Set<String>) redisService.get(Constants.USER_PERMISSION_CACHE);

        if (set==null){
            set = sysUserService.queryPermissions(user.getId());
        }


        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.setStringPermissions(set);
        return info;
    }

    /**
     * 认证(登录时调用)
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(
            AuthenticationToken token) throws AuthenticationException {
        String loginName = (String) token.getPrincipal();
        String password = new String((char[]) token.getCredentials());

        SysUser sysUser = null;

        //查询用户信息
        sysUser = new SysUser();
        sysUser.setLoginName(loginName);
        SysUser user = sysUserService.findByNameOrPass(sysUser);

        //账号不存在
        if (user == null) {
            throw new UnknownAccountException("账号或密码不正确");
        }
        //密码错误
        if (!password.equals(user.getPassword())) {
            throw new IncorrectCredentialsException("账号或密码不正确");
        }

        if (user.getLoginFlag().equals(Constants.LOGIN_FLAG)){
            throw new DisabledAccountException("该账号已被禁止登录,请联系管理员！");
        }

        Set<String> set = sysUserService.queryPermissions(user.getId());

        // 用户登录缓存用户信息
        redisService.set(Constants.USER_CACHE+user.getId(),user);
        // 缓存用户权限信息
        redisService.set(Constants.USER_PERMISSION_CACHE+user.getId(),set);

        // 把当前用户放入到session中
        Subject subject = SecurityUtils.getSubject();
        Session session = subject.getSession(true);
        session.setAttribute(CURRENT_USER, user);
        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, password, getName());

        user.setLoginDate(new Date());
        user.setLoginIp(subject.getSession().getHost());
        sysUserService.save(user);

        return info;
    }

    /**
     * 清理缓存权限
     */
    public void clearCachedAuthorizationInfo() {
        this.clearCachedAuthorizationInfo(SecurityUtils.getSubject().getPrincipals());
    }

}
